package main

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
	pb "github.com/hyperledger/fabric/protos/peer"
	"github.com/skip2/go-qrcode"
	"hash"
	"time"
)

func (f FarmingChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	//初始化一个企业以及一个企业的子账户 初始化两个场地 初始化两个资产
	//初始化一个子账户
	sub := SubAccount{
		Id:         "2001",
		Password:   "123456",
		Name:       "王大壮",
		Address:    "安徽省合肥市瑶海区",
		Phone:      "15655649906",
		Subjection: "1001",
	}
	//对密码进行MD5加密
	sub.Password = Hash(sub.Password, "md5", false, false)
	subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{sub.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := json.Marshal(sub)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(subKey, subByte); err != nil {
		return shim.Error("put state error ")
	}
	//初始化两个场地
	spa1 := Space{
		Id:            "3001",
		Name:          "王家畈",
		Subjection:    "1001",
		Address:       "王家畈田",
		Type:          SpaceType1,
		Size:          "10亩",
		TestFertility: nil,
		AddFertility:  nil,
	}
	spa2 := Space{
		Id:            "3002",
		Name:          "test",
		Subjection:    "1001",
		Address:       "水果和德国哈吉",
		Type:          SpaceType2,
		Size:          "5亩",
		TestFertility: nil,
		AddFertility:  nil,
	}
	spa := []Space{spa1, spa2}
	for i := 0; i < len(spa); i++ {
		spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{spa[i].Id})
		if err != nil {
			return shim.Error("create key error ")
		}
		spaByte, err := json.Marshal(spa[i])
		if err != nil {
			return shim.Error("marshal error ")
		}
		if err := stub.PutState(spaKey, spaByte); err != nil {
			return shim.Error("put state error ")
		}
	}
	//初始化两个资产
	aa, _ := time.ParseDuration("24h")
	ass1 := Assets{
		Id:           "4001",
		Name:         "水稻种",
		Subjection:   "1001",
		PurchaseDate: time.Now(),
		Type:         AssetsType1,
		Desc:         "10kg",
		Production:   "安徽农种",
		OverdueDate:  time.Now().Add(60 * aa), //过期时间
	}
	ass2 := Assets{
		Id:           "4002",
		Name:         "鱼苗",
		Subjection:   "1001",
		PurchaseDate: time.Now(),
		Type:         AssetsType2,
		Desc:         "10kg",
		Production:   "安徽农种",
		OverdueDate:  time.Now().Add(60 * aa), //过期时间
	}
	ass := []Assets{ass1, ass2}
	for i := 0; i < len(spa); i++ {
		assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{ass[i].Id})
		if err != nil {
			return shim.Error("create key error ")
		}
		assByte, err := json.Marshal(spa[i])
		if err != nil {
			return shim.Error("marshal error ")
		}
		if err := stub.PutState(assKey, assByte); err != nil {
			return shim.Error("put state error ")
		}
	}
	//初始化一个企业
	comp1 := Company{
		Id:             "1001",
		Password:       "123456",
		Name:           "安徽省智能农业管理中心",
		Address:        "安徽省合肥市",
		Desc:           "国企",
		EnterpriseCode: "an12348965",
		Phone:          "23608888",
		Email:          "26367281@qq.com",
		Website:        "zts.com",
		Subaccount:     []SubAccount{sub},
		Space:          []Space{spa1, spa2},
		Assets:         []Assets{ass1, ass2},
	}
	comp1.Password = Hash(comp1.Password, "md5", false, false)
	comp1Key, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{comp1.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	comp1Byte, err := json.Marshal(comp1)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(comp1Key, comp1Byte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(nil)
}

func (f FarmingChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	fun, args := stub.GetFunctionAndParameters()
	switch fun {
	case "createCompany": //创建公司即注册公司
		return createCompany(stub, args)
	case "updateCompany": //修改公司
		return updateCompany(stub, args)
	case "createSubAccount": //创建子账户
		return createSubAccount(stub, args)
	case "updateSubAccount": //修改子账户
		return updateSubAccount(stub, args)
	case "delCompany": //公司注销，即删除公司
		return delCompany(stub, args)
	case "delSubAccount": //删除公司的某个子账户
		return delSubAccount(stub, args)
	case "queryCompany": //查询公司
		return queryCompany(stub, args)
	case "queryAllCompany": //查询所有公司
		return queryAllCompany(stub, args)
	case "querySubAccount": //查询子账户
		return querySubAccount(stub, args)
	case "querySubAccounts": //查询公司旗下所有子账户
		return querySubAccounts(stub, args)
	case "querySpaces": //查询公司旗下所有子账户
		return querySpaces(stub, args)
	case "queryAssetss": //查询公司旗下所有子账户
		return queryAssetss(stub, args)
	//以上为账号管理模块
	case "createSpace":
		return createSpace(stub, args)
	case "updateSpace":
		return updateSpace(stub, args)
	case "delSpace":
		return delSpace(stub, args)
	case "querySpace":
		return querySpace(stub, args)
	//以上为场地功能模块
	case "createAssets":
		return createAssets(stub, args)
	case "updateAssets":
		return updateAssets(stub, args)
	case "delAssets":
		return delAssets(stub, args)
	case "queryAssets":
		return queryAssets(stub, args)
	//以上为资产功能模块
	case "createTestFertility": //为场地测试肥力 不可删除更改
		return createTestFertility(stub, args)
	case "createAddFertility": //为场地施肥
		return createAddFertility(stub, args)
	case "createCrops": //创建一个农作物
		return createCrops(stub, args)
	case "createFarming": //创建一个农事结构体
		return createFarming(stub, args)
	case "updateCrops": //更新农作物状态
		return updateCrops(stub, args)
	case "pickCrops": //采摘农作物
		return pickCrops(stub, args)
	case "queryPick": //查询采摘的农作物
		return queryPick(stub, args)
	//以上为农事功能模块
	case "createMachining": //加工农作物
		return createMachining(stub, args)
	case "inStock": //入仓
		return inStock(stub, args)
	case "outStock": //出仓
		return outStock(stub, args)
	case "createOrder"://创建订单
		return createOrder(stub,args)
	case "addLogistics"://添加物流信息
		return addLogistics(stub,args)
	case "confirmOrder"://确认交易完成
		return confirmOrder(stub,args)
	case "queryOrder"://确认交易完成
		return queryOrder(stub,args)
	case "traceBackTo"://追溯订单
		return traceBackTo(stub,args)
	case "renovateCompany": //更新企业旗下子账户 防止修改了子账户 不同步的问题
		return renovateCompany(stub, args)
	case "login": //更新企业旗下子账户 防止修改了子账户 不同步的问题
		return login(stub, args)
	case "generateQrCode": // 生成二维码图片
		return generateQrCode(stub, args)
	case "showQrCode":
		return showQrCode(stub, args)
	case "uploadImg":
		return uploadImg(stub, args)
	case "sendCompanyImg":
		return sendCompanyImg(stub, args)
	}
	return shim.Error("not find function")
}

// 生成二维码信息
func generateQrCode(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	err := qrcode.WriteFile("http://192.168.0.111:8080/#/codePage?subId=" + args[0] + "&companyId=" + args[1], qrcode.Medium, 256, "/home/work/go/src/Agricultural/QrCode/" + args[0] + ".png")
	if err != nil {

	}
	return shim.Success(nil)
}

func showQrCode(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	//file, err := os.Open("/home/work/go/src/Agricultural/QrCode/" + args[0] + ".png")
	//if err != nil {
	//	return shim.Error("osOpen Error")
	//}
	//defer file.Close()
	//buff, err := ioutil.ReadAll(file)
	//if err != nil {
	//	return shim.Error("ReadAll Error")
	//}
	result := "/home/work/go/src/Agricultural/QrCode/" + args[0] + ".png"
	return shim.Success([]byte(result))
}

func uploadImg(stub shim.ChaincodeStubInterface, args []string) pb.Response  {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var companyImg CompanyImg
	if err := json.Unmarshal([]byte(args[0]), &companyImg); err != nil {
		return shim.Error("unmarshal error ")
	}
	if companyImg.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符合",
			Payload: nil,
		}
	}
	//创建组合键序列化保存至账本
	subKey, err := stub.CreateCompositeKey(CompanyImgKeyPrefix, []string{companyImg.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := json.Marshal(companyImg)
	if err != nil {
		return shim.Error("marshal error")
	}
	//同步更新公司子账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加公司子账户
	comp.Imgs = append(comp.Imgs, companyImg)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	//保存子账户至账本
	if err := stub.PutState(subKey, subByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(subByte)
}

func sendCompanyImg(stub shim.ChaincodeStubInterface, args []string) pb.Response  {
	result := "/home/work/go/src/Agricultural/image/" + args[0]
	return shim.Success([]byte(result))
}

//更新企业旗下的子账户、场地、资产、储存 传入公司id
func renovateCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//更新子账户
	var subs []SubAccount
	for i := 0; i < len(comp.Subaccount); i++ {
		subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{comp.Subaccount[i].Id})
		if err != nil {
			return shim.Error("create key error")
		}
		subByte, err := stub.GetState(subKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		var sub SubAccount
		if err := json.Unmarshal(subByte, &sub); err != nil {
			return shim.Error("unmarshal error ")
		}
		subs = append(subs, sub)
	}
	comp.Subaccount = subs
	//更新场地
	var spas []Space
	for i := 0; i < len(comp.Space); i++ {
		spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{comp.Space[i].Id})
		if err != nil {
			return shim.Error("create key error")
		}
		spaByte, err := stub.GetState(spaKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		var spa Space
		if err := json.Unmarshal(spaByte, &spa); err != nil {
			return shim.Error("unmarshal error ")
		}
		spas = append(spas, spa)
	}
	comp.Space = spas
	//更新资产
	var asss []Assets
	for i := 0; i < len(comp.Assets); i++ {
		assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{comp.Assets[i].Id})
		if err != nil {
			return shim.Error("create key error")
		}
		assByte, err := stub.GetState(assKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		var ass Assets
		if err := json.Unmarshal(assByte, &ass); err != nil {
			return shim.Error("unmarshal error ")
		}
		asss = append(asss, ass)
	}
	comp.Assets = asss
	//更新农作物存储
	var pics []Pick
	for i := 0; i < len(comp.Storage); i++ {
		picKey, err := stub.CreateCompositeKey(PickKeyPrefix, []string{comp.Storage[i].Id})
		if err != nil {
			return shim.Error("create key error")
		}
		picByte, err := stub.GetState(picKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		var pic Pick
		if err := json.Unmarshal(picByte, &pic); err != nil {
			return shim.Error("unmarshal error ")
		}
		pics = append(pics, pic)
	}
	comp.Storage = pics
	//更新加工存储
	var macs []Machining
	for i := 0; i < len(comp.Machinings); i++ {
		macKey, err := stub.CreateCompositeKey(MachiningKeyPrefix, []string{comp.Machinings[i].Id})
		if err != nil {
			return shim.Error("create key error")
		}
		macByte, err := stub.GetState(macKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		var mac Machining
		if err := json.Unmarshal(macByte, &mac); err != nil {
			return shim.Error("unmarshal error ")
		}
		macs = append(macs, mac)
	}
	comp.Machinings = macs
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error")
	}
	return shim.Success(compByteNew)
}

//传入企业结构体 创建企业，即企业注册
func createCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal([]byte(args[0]), &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段是否为空
	if comp.Id == "" || comp.Password == "" || comp.Name == "" || comp.Address == "" || comp.EnterpriseCode == "" || comp.Phone == "" || comp.Email == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "必要字段为空",
			Payload: nil,
		}
	}
	//对密码加密
	comp.Password = Hash(comp.Password, "md5", false, false)
	//创建组合键序列化保存至账本
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{comp.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	compByte, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(compKey, compByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(compByte)
}

//传入企业结构体 修改企业
func updateCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal([]byte(args[0]), &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段是否为空
	if comp.Id == "" || comp.Password == "" || comp.Name == "" || comp.Address == "" || comp.EnterpriseCode == "" || comp.Phone == "" || comp.Email == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "必要字段为空",
			Payload: nil,
		}
	}
	//对密码加密
	comp.Password = Hash(comp.Password, "md5", false, false)
	//创建组合键序列化保存至账本
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{comp.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	compByte, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(compKey, compByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(compByte)
}

//企业创建子账户交由农户管理 传入子账户结构体 操作公司id
func createSubAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var sub SubAccount
	if err := json.Unmarshal([]byte(args[0]), &sub); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段是否为空
	if sub.Id == "" || sub.Password == "" || sub.Name == "" || sub.Address == "" || sub.Phone == "" || sub.Subjection == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "必要字段为空",
			Payload: nil,
		}
	}
	if sub.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符合",
			Payload: nil,
		}
	}
	//对密码加密
	sub.Password = Hash(sub.Password, "md5", false, false)
	//创建组合键序列化保存至账本
	subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{sub.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := json.Marshal(sub)
	if err != nil {
		return shim.Error("marshal error")
	}
	//同步更新公司子账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加公司子账户
	comp.Subaccount = append(comp.Subaccount, sub)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	//保存子账户至账本
	if err := stub.PutState(subKey, subByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(subByte)
}

//企业修改子账户交由农户管理 传入子账户结构体 操作公司id
func updateSubAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var sub SubAccount
	if err := json.Unmarshal([]byte(args[0]), &sub); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段是否为空
	if sub.Id == "" || sub.Password == "" || sub.Name == "" || sub.Address == "" || sub.Phone == "" || sub.Subjection == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "必要字段为空",
			Payload: nil,
		}
	}
	if sub.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	//对密码加密
	sub.Password = Hash(sub.Password, "md5", false, false)
	//创建组合键序列化保存至账本
	subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{sub.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := json.Marshal(sub)
	if err != nil {
		return shim.Error("marshal error")
	}
	//同步更新公司子账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加公司子账户
	comp.Subaccount = append(comp.Subaccount, sub)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(subKey, subByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(subByte)
}

//删除公司传入公司id
func delCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	//删除公司名下子账户以及场地 资产
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//删除名下子账户
	for i := 0; i < len(comp.Subaccount); i++ {
		subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{comp.Subaccount[i].Id})
		if err != nil {
			return shim.Error("create key error ")
		}
		if err := stub.DelState(subKey); err != nil {
			return shim.Error("del state error ")
		}
	}
	//删除名下场地
	for i := 0; i < len(comp.Space); i++ {
		spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{comp.Space[i].Id})
		if err != nil {
			return shim.Error("create key error ")
		}
		if err := stub.DelState(spaKey); err != nil {
			return shim.Error("del state error ")
		}
	}
	//删除名下资产
	for i := 0; i < len(comp.Assets); i++ {
		assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{comp.Assets[i].Id})
		if err != nil {
			return shim.Error("create key error ")
		}
		if err := stub.DelState(assKey); err != nil {
			return shim.Error("del state error ")
		}
	}
	//删除公司
	if err := stub.DelState(compKey); err != nil {
		return shim.Error("del state error ")
	}
	return shim.Success(nil)
}

//公司删除旗下的子账户 传入子账户id 以及公司id
func delSubAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	//创建子账户组合键
	subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := stub.GetState(subKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(subByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到子账户",
			Payload: nil,
		}
	}
	var sub SubAccount
	if err := json.Unmarshal(subByte, &sub); err != nil {
		return shim.Error("unmarshal error ")
	}
	if sub.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	//按照组合键删除子账户
	if err := stub.DelState(subKey); err != nil {
		return shim.Error("del state error ")
	}
	//同步更新公司子账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//删除这个子账户  遍历查找id相同的
	for i := 0; i < len(comp.Subaccount); i++ {
		if comp.Subaccount[i].Id == sub.Id {
			//删除这个数组元素
			comp.Subaccount = append(comp.Subaccount[:i], comp.Subaccount[i+1:]...)
		}
	}
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(nil)
}

//查询公司 传入公司id
func queryCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到账户",
			Payload: nil,
		}
	}
	return shim.Success(compByte)
}

// 查询所有公司
func queryAllCompany(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	companyResult, err := stub.GetStateByPartialCompositeKey(CompanyKeyPrefix, []string{})
	if err != nil {
		return shim.Error("GetStateByPartialCompositeKey Error")
	}
	defer companyResult.Close()
	var companys []Company
	for companyResult.HasNext() {
		val, err := companyResult.Next()
		if err != nil {
			return shim.Error(fmt.Sprintf("resultIterator error: %s", err))
		}

		var company Company
		if err := json.Unmarshal(val.GetValue(), &company); err != nil {
			return shim.Error(fmt.Sprintf("unmarshal error: %s", err))
		}

		companys = append(companys, company)
	}
	result, err := json.Marshal(companys)
	if err != nil {
		return shim.Error("Marshal Error")
	}
	return shim.Success(result)
}

//查询子账户 传入子账户id 以及公司id
func querySubAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	subKey, err := stub.CreateCompositeKey(SubAccountKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	subByte, err := stub.GetState(subKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(subByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到账户",
			Payload: nil,
		}
	}
	var sub SubAccount
	if err := json.Unmarshal(subByte, &sub); err != nil {
		return shim.Error("unmarshal error ")
	}
	//if sub.Subjection != args[1] {
	//	return pb.Response{
	//		Status:  shim.ERRORTHRESHOLD,
	//		Message: "无权限",
	//		Payload: nil,
	//	}
	//}
	return shim.Success(subByte)
}

//查询公司旗下的所有子账户  传入公司id
func querySubAccounts(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	subAccounts := comp.Subaccount
	subAccountsByte, err := json.Marshal(subAccounts)
	if err != nil {
		return shim.Error("marshal error")
	}
	return shim.Success(subAccountsByte)
}

//查询公司旗下的所有子场地  传入公司id
func querySpaces(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	spaces := comp.Space
	spacesByte, err := json.Marshal(spaces)
	if err != nil {
		return shim.Error("marshal error")
	}
	return shim.Success(spacesByte)
}

//查询公司旗下的所有资产  传入公司id
func queryAssetss(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	ass := comp.Assets
	aaaByte, err := json.Marshal(ass)
	if err != nil {
		return shim.Error("marshal error")
	}
	return shim.Success(aaaByte)
}

//公司录入一个场地 传入一个场地结构体以及公司id
func createSpace(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal([]byte(args[0]), &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段的正确性
	if spa.Id == "" || spa.Name == "" || spa.Subjection == "" || spa.Address == "" || spa.Type == "" || spa.Size == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段为空",
			Payload: nil,
		}
	}
	//验证隶属id是否相同
	if spa.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符",
			Payload: nil,
		}
	}
	//创建主键保存至数组并更新公司场地
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{spa.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := json.Marshal(spa)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//更新公司场地
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加场地
	comp.Space = append(comp.Space, spa)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(spaKey, spaByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(spaByte)
}

//公司修改场地 传入一个场地结构体 以及公司id
func updateSpace(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal([]byte(args[0]), &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段的正确性
	if spa.Id == "" || spa.Name == "" || spa.Subjection == "" || spa.Address == "" || spa.Type == "" || spa.Size == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段为空",
			Payload: nil,
		}
	}
	//验证隶属id是否相同
	if spa.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符",
			Payload: nil,
		}
	}
	//创建主键保存至数组并更新公司场地
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{spa.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := json.Marshal(spa)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(spaKey, spaByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(spaByte)
}

//公司删除场地，传入场地id 以及公司id
func delSpace(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	//创建场地组合键
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := stub.GetState(spaKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(spaByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到子账户",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal(spaByte, &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	if spa.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	//按照组合键删除子账户
	if err := stub.DelState(spaKey); err != nil {
		return shim.Error("del state error ")
	}
	//同步更新公司子账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//删除这个子账户  遍历查找id相同的
	for i := 0; i < len(comp.Space); i++ {
		if comp.Space[i].Id == spa.Id {
			//删除这个数组元素
			comp.Subaccount = append(comp.Subaccount[:i], comp.Subaccount[i+1:]...)
		}
	}
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(nil)
}

//查询场地 传入场地id 以及公司id
func querySpace(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := stub.GetState(spaKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(spaByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到账户",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal(spaByte, &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	if spa.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	return shim.Success(spaByte)
}

//公司录入一个资产 传入一个资产结构体以及公司id
func createAssets(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var ass Assets
	if err := json.Unmarshal([]byte(args[0]), &ass); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段的正确性
	if ass.Id == "" || ass.Name == "" || ass.Subjection == "" || ass.Type == "" || ass.Desc == "" || ass.Production == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段为空",
			Payload: nil,
		}
	}
	//验证隶属id是否相同
	if ass.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符",
			Payload: nil,
		}
	}
	//创建主键保存至账本并更新公司资产
	assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{ass.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	assByte, err := json.Marshal(ass)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//更新公司场地
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加资产
	comp.Assets = append(comp.Assets, ass)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(assKey, assByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(assByte)
}

//公司修改资产 传入一个资产结构体 以及公司id
func updateAssets(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var ass Assets
	if err := json.Unmarshal([]byte(args[0]), &ass); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证字段的正确性
	if ass.Id == "" || ass.Name == "" || ass.Subjection == "" || ass.Type == "" || ass.Desc == "" || ass.Production == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段为空",
			Payload: nil,
		}
	}
	//验证隶属id是否相同
	if ass.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "隶属企业不符",
			Payload: nil,
		}
	}
	//创建主键保存至数组并更新公司资产
	assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{ass.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	assByte, err := json.Marshal(ass)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(assKey, assByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(assByte)
}

//公司删除资产，传入资产id 以及公司id
func delAssets(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	//创建场地组合键
	assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	assByte, err := stub.GetState(assKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(assByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到子账户",
			Payload: nil,
		}
	}
	var ass Assets
	if err := json.Unmarshal(assByte, &ass); err != nil {
		return shim.Error("unmarshal error ")
	}
	if ass.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	//按照组合键删除资产
	if err := stub.DelState(assKey); err != nil {
		return shim.Error("del state error ")
	}
	//同步更新公司资产
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	//删除这个子账户  遍历查找id相同的
	for i := 0; i < len(comp.Assets); i++ {
		if comp.Assets[i].Id == ass.Id {
			//删除这个数组元素
			comp.Assets = append(comp.Assets[:i], comp.Assets[i+1:]...)
		}
	}
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(nil)
}

//查询资产 传入资产id 以及公司id
func queryAssets(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	assKey, err := stub.CreateCompositeKey(AssetsKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	assByte, err := stub.GetState(assKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(assByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到账户",
			Payload: nil,
		}
	}
	var ass Assets
	if err := json.Unmarshal(assByte, &ass); err != nil {
		return shim.Error("unmarshal error ")
	}
	if ass.Subjection != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "无权限",
			Payload: nil,
		}
	}
	return shim.Success(assByte)
}

//创建测试肥力 传入肥力结构体 以及场地id
func createTestFertility(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var testFer TestFertility
	if err := json.Unmarshal([]byte(args[0]), &testFer); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if testFer.Id == "" || testFer.Space == "" || testFer.Tester == "" || testFer.Type == "" || testFer.OrganicMatter <= 0 || testFer.Alkali <= 0 || testFer.Phosphorus <= 0 || testFer.Potassium <= 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "参数不合法",
			Payload: nil,
		}
	}
	if testFer.Space != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入场地id不符",
			Payload: nil,
		}
	}
	//更新场地测试
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := stub.GetState(spaKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(spaByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到场地",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal(spaByte, &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	spa.TestFertility = append(spa.TestFertility, testFer)
	spaByteNew, err := json.Marshal(spa)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(spaKey, spaByteNew); err != nil {
		return shim.Error("put state error ")
	}
	//将测试保存至账本
	testKey, err := stub.CreateCompositeKey(TestFertilityKeyPrefix, []string{testFer.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	testByte, err := json.Marshal(testFer)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(testKey, testByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(testByte)
}

//为场地施肥  传入肥力结构体  以及场地id
func createAddFertility(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var AddFer AddFertility
	if err := json.Unmarshal([]byte(args[0]), &AddFer); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if AddFer.Id == "" || AddFer.Space == "" || AddFer.Name == "" || AddFer.Fertility == "" || AddFer.Tester == "" || AddFer.Type == "" || AddFer.Quality <= 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "参数不合法",
			Payload: nil,
		}
	}
	if AddFer.Space != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入场地id不符",
			Payload: nil,
		}
	}
	//更新场地测试
	spaKey, err := stub.CreateCompositeKey(SpaceKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error ")
	}
	spaByte, err := stub.GetState(spaKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(spaByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到场地",
			Payload: nil,
		}
	}
	var spa Space
	if err := json.Unmarshal(spaByte, &spa); err != nil {
		return shim.Error("unmarshal error ")
	}
	spa.AddFertility = append(spa.AddFertility, AddFer)
	spaByteNew, err := json.Marshal(spa)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(spaKey, spaByteNew); err != nil {
		return shim.Error("put state error ")
	}
	//将测试保存至账本
	addKey, err := stub.CreateCompositeKey(AddFertilityKeyPrefix, []string{AddFer.Id})
	if err != nil {
		return shim.Error("create key error")
	}
	addByte, err := json.Marshal(AddFer)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err := stub.PutState(addKey, addByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(addByte)
}

//创建一个农作物对象 传入农作物结构体 以及 责任人id
func createCrops(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var cro Crops
	if err := json.Unmarshal([]byte(args[0]), &cro); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if cro.Id == "" || cro.Name == "" || cro.Cycle <= 0 || cro.PersonLiable == "" || cro.Type == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入参数不符",
			Payload: nil,
		}
	}
	if cro.PersonLiable != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "责任人id不符",
			Payload: nil,
		}
	}
	if cro.Type != CropsType1 || cro.Type != CropsType2 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "类型错误",
			Payload: nil,
		}
	}
	cro.Status = CropsStatus1
	croByte, err := json.Marshal(cro)
	if err != nil {
		return shim.Error("marshal error ")
	}
	croKey, err := stub.CreateCompositeKey(CropsKeyPrefix, []string{cro.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	if err := stub.PutState(croKey, croByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(croByte)
}

//创建一个农事对象 传入农事结构体 以及录入人员id
func createFarming(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var far Farming
	if err := json.Unmarshal([]byte(args[0]), &far); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if far.Id == "" || far.CropsId == "" || far.Name == "" || far.Space == "" || far.Tester == "" || far.Type == "" || far.Desc == "" {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入参数不符",
			Payload: nil,
		}
	}
	if far.Tester != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "责任人id不符",
			Payload: nil,
		}
	}
	farByte, err := json.Marshal(far)
	if err != nil {
		return shim.Error("marshal error ")
	}
	farKey, err := stub.CreateCompositeKey(FarmingKeyPrefix, []string{far.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	//更新农作物农事
	croKey, err := stub.CreateCompositeKey(CropsKeyPrefix, []string{far.CropsId})
	if err != nil {
		return shim.Error("create key error ")
	}
	croByte, err := stub.GetState(croKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(croByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到该农作物",
			Payload: nil,
		}
	}
	var cro Crops
	if err := json.Unmarshal(croByte, &cro); err != nil {
		return shim.Error("unmarshal error ")
	}
	//添加农事
	cro.Farmings = append(cro.Farmings, far)
	croByteNew, err := json.Marshal(cro)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(croKey, croByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(farKey, farByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(croByte)
}

//更新农作物状态 传入农作物id 以及状态
func updateCrops(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	//验证状态
	if args[1] != CropsStatus1 || args[1] != CropsStatus2 || args[1] != CropsStatus3 || args[1] != CropsStatus4 || args[1] != CropsStatus5 || args[1] != CropsStatus6 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "状态出错",
			Payload: nil,
		}
	}
	croKey, err := stub.CreateCompositeKey(CropsKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	croByte, err := stub.GetState(croKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(croByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到该农作物",
			Payload: nil,
		}
	}
	var cro Crops
	if err := json.Unmarshal(croByte, &cro); err != nil {
		return shim.Error("unmarshal error ")
	}
	cro.Status = args[1]
	croByteNew, err := json.Marshal(cro)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(croKey, croByteNew); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(croByteNew)
}

//采摘农作物 传入采摘农作物结构体 以及采摘人员id 采摘的结果需要录入公司账户
func pickCrops(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var pic Pick
	if err := json.Unmarshal([]byte(args[0]), &pic); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if pic.Id == "" || pic.Name == "" || pic.Subjection == "" || pic.CropsId == "" || pic.Tester == "" || pic.Weight <= 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入参数不符",
			Payload: nil,
		}
	}
	if pic.Tester != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "责任人id不符",
			Payload: nil,
		}
	}
	picByte, err := json.Marshal(pic)
	if err != nil {
		return shim.Error("marshal error ")
	}
	picKey, err := stub.CreateCompositeKey(PickKeyPrefix, []string{pic.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	//录入公司账户
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	comp.Storage = append(comp.Storage, pic)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(picKey, picByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(picByte)
}

//查询农作物 传入农作物id
func queryPick(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	picKey, err := stub.CreateCompositeKey(PickKeyPrefix, []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	picByte, err := stub.GetState(picKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(picByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该农作物",
			Payload: nil,
		}
	}
	return shim.Success(picByte)
}

//加工农作物 传入采摘农作物结构体 以及加工人员id 加工需要
func createMachining(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var mac Machining
	if err := json.Unmarshal([]byte(args[0]), &mac); err != nil {
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if mac.Id == "" || mac.Name == "" || mac.Subjection == "" || mac.PickId == "" || mac.Tester == "" || mac.OriginalWeight <= 0 || mac.Weight <= 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "传入参数不符",
			Payload: nil,
		}
	}
	if mac.Tester != args[1] {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "责任人id不符",
			Payload: nil,
		}
	}
	macByte, err := json.Marshal(mac)
	if err != nil {
		return shim.Error("marshal error ")
	}
	macKey, err := stub.CreateCompositeKey(MachiningKeyPrefix, []string{mac.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	//更新公司账户农作物库存并将加工的存入公司账户
	picKey, err := stub.CreateCompositeKey(PickKeyPrefix, []string{mac.PickId})
	if err != nil {
		return shim.Error("create key error ")
	}
	picByte, err := stub.GetState(picKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(picByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该农作物",
			Payload: nil,
		}
	}
	var pic Pick
	if err := json.Unmarshal(picByte, &pic); err != nil {
		return shim.Error("unmarshal error ")
	}
	//更新采摘的重量
	if pic.Weight < mac.OriginalWeight {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "库存不足",
			Payload: nil,
		}
	}
	pic.Weight -= mac.OriginalWeight
	picByteNew, err := json.Marshal(pic)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err := stub.PutState(picKey, picByteNew); err != nil {
		return shim.Error("put state error ")
	}

	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未找到该公司",
			Payload: nil,
		}
	}
	var comp Company
	if err := json.Unmarshal(compByte, &comp); err != nil {
		return shim.Error("unmarshal error ")
	}
	comp.Machinings = append(comp.Machinings, mac)
	//序列化保存至账本
	compByteNew, err := json.Marshal(comp)
	if err != nil {
		return shim.Error("marshal error ")
	}
	//保存公司至账本
	if err := stub.PutState(compKey, compByteNew); err != nil {
		return shim.Error("put state error ")
	}
	if err := stub.PutState(macKey, macByte); err != nil {
		return shim.Error("put state error ")
	}
	return shim.Success(picByte)
}
//入仓 传入 stock 结构体 入仓管理员id
func inStock(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	var sto Stock
	if err:=json.Unmarshal([]byte(args[0]),&sto);err!=nil{
		return shim.Error("unmarshal error ")
	}
	//验证参数
	if sto.Id==""||sto.Subjection==""||len(sto.StockId)==0||sto.inTester!=args[1]{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "参数不符",
			Payload:              nil,
		}
	}
	stoKey,err:=stub.CreateCompositeKey(StockKeyPrefix,[]string{args[1]})
	if err != nil {
		return shim.Error("create key error")
	}
	stoByte,err:=json.Marshal(sto)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err:=stub.PutState(stoKey,stoByte);err!=nil{
		return shim.Error("put state error ")
	}
	return shim.Success(stoByte)
}
//出仓 传入仓储id 出仓管理员id
func outStock(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  0,
			Message: "",
			Payload: nil,
		}
	}
	stoKey,err:=stub.CreateCompositeKey(StockKeyPrefix,[]string{args[0]})
	if err != nil {
		return shim.Error("create key error")
	}
	stoByte,err:=stub.GetState(stoKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	var sto Stock
	if err:=json.Unmarshal(stoByte,&sto);err!=nil{
		return shim.Error("unmarshal error ")
	}
	sto.outTester=args[1]
	sto.outTime=time.Now()
	stoByteNew,err:=json.Marshal(sto)
	if err != nil {
		return shim.Error("marshal error")
	}
	if err:=stub.PutState(stoKey,stoByteNew);err!=nil{
		return shim.Error("put state error ")
	}
	return shim.Success(stoByteNew)
}
//创建订单 传入订单结构体
func createOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var ord Order
	if err:=json.Unmarshal([]byte(args[0]),&ord);err!=nil{
		return shim.Error("unmarshal error")
	}
	if ord.Id==""||ord.Compid==""||ord.Purchase==""||ord.Type!=Ordertype1||ord.Type!=Ordertype2||ord.Weight<=0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "参数出错",
			Payload:              nil,
		}
	}
	//查询公司
	compKey, err := stub.CreateCompositeKey(CompanyKeyPrefix, []string{ord.Compid})
	if err != nil {
		return shim.Error("create key error ")
	}
	compByte, err := stub.GetState(compKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(compByte) == 0 {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "未查询到账户",
			Payload: nil,
		}
	}
	var comp Company
	if err:=json.Unmarshal(compByte,&comp);err!=nil{
		return shim.Error("unmarshal error ")
	}
	if ord.Type==Ordertype1{
		//修改账本中未加工产品存储
		picKey, err := stub.CreateCompositeKey(PickKeyPrefix, []string{ord.Purchase})
		if err != nil {
			return shim.Error("create key error ")
		}
		picByte, err := stub.GetState(picKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		if len(picByte) == 0 {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "未找到该农作物",
				Payload: nil,
			}
		}
		var pic Pick
		if err := json.Unmarshal(picByte, &pic); err != nil {
			return shim.Error("unmarshal error ")
		}
		if pic.Weight<ord.Weight{
			return pb.Response{
				Status:               shim.ERRORTHRESHOLD,
				Message:              "库存不足",
				Payload:              nil,
			}
		}
		pic.Weight-=ord.Weight
		picByteNew, err := json.Marshal(pic)
		if err != nil {
			return shim.Error("marshal error ")
		}
		if err := stub.PutState(picKey, picByteNew); err != nil {
			return shim.Error("put state error ")
		}
	}
	if ord.Type==Ordertype2{
		//修改账本中已加工产品存储
		macKey, err := stub.CreateCompositeKey(MachiningKeyPrefix, []string{ord.Purchase})
		if err != nil {
			return shim.Error("create key error ")
		}
		macByte, err := stub.GetState(macKey)
		if err != nil {
			return shim.Error("get state error ")
		}
		if len(macByte) == 0 {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "未找到该农作物",
				Payload: nil,
			}
		}
		var mac Machining
		if err := json.Unmarshal(macByte, &mac); err != nil {
			return shim.Error("unmarshal error ")
		}
		if mac.Weight<ord.Weight{
			return pb.Response{
				Status:               shim.ERRORTHRESHOLD,
				Message:              "库存不足",
				Payload:              nil,
			}
		}
		mac.Weight-=ord.Weight
		macByteNew, err := json.Marshal(mac)
		if err != nil {
			return shim.Error("marshal error ")
		}
		if err := stub.PutState(macKey, macByteNew); err != nil {
			return shim.Error("put state error ")
		}
	}
	ordKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{ord.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	ord.Status=OrderStatus1
	ordByte,err:=json.Marshal(ord)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err:=stub.PutState(ordKey,ordByte);err!=nil{
		return shim.Error("put state error")
	}
	return shim.Success(ordByte)
}
//添加物流信息 传入物流信息结构体 以及订单id
func addLogistics(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 2)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	var log Logistics
	if err:=json.Unmarshal([]byte(args[0]),&log);err!=nil{
		return shim.Error("unmarshal error")
	}
	if log.Id==""||log.Address==""{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "参数错误",
			Payload:              nil,
		}
	}
	logKey,err:=stub.CreateCompositeKey(LogisticsKeyPrefix,[]string{log.Id})
	if err != nil {
		return shim.Error("create key error ")
	}
	logByte,err:=json.Marshal(log)
	if err != nil {
		return shim.Error("marshal error")
	}
	ordKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{args[1]})
	if err != nil {
		return shim.Error("create key error ")
	}
	ordByte,err:=stub.GetState(ordKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(ordByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "为查询到订单",
			Payload:              nil,
		}
	}
	var ord Order
	if err:=json.Unmarshal(ordByte,&ord);err!=nil{
		return shim.Error("unmarshal error ")
	}
	ord.Logistics= append(ord.Logistics, log)
	ordByteNew,err:=json.Marshal(ord)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err:= stub.PutState(logKey,logByte);err!=nil{
		return shim.Error("put state error ")
	}
	if err:= stub.PutState(ordKey,ordByteNew);err!=nil{
		return shim.Error("put state error ")
	}
	return shim.Success(ordByteNew)
}
//确认交易完成 传入订单id
func confirmOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	ordKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	ordByte,err:=stub.GetState(ordKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(ordByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "为查询到订单",
			Payload:              nil,
		}
	}
	var ord Order
	if err:=json.Unmarshal(ordByte,&ord);err!=nil{
		return shim.Error("unmarshal error ")
	}
	ord.Status=OrderStatus2
	ordByteNew,err:=json.Marshal(ord)
	if err != nil {
		return shim.Error("marshal error ")
	}
	if err:= stub.PutState(ordKey,ordByteNew);err!=nil{
		return shim.Error("put state error ")
	}
	return shim.Success(ordByteNew)
}
//查询订单
func queryOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	ordKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	ordByte,err:=stub.GetState(ordKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(ordByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "为查询到订单",
			Payload:              nil,
		}
	}
	return shim.Success(ordByte)
}
//追溯订单 订单id
func traceBackTo(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking(args, 1)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	ordKey,err:=stub.CreateCompositeKey(OrderKeyPrefix,[]string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	ordByte,err:=stub.GetState(ordKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	if len(ordByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "为查询到订单",
			Payload:              nil,
		}
	}
	var ord Order
	if err:=json.Unmarshal(ordByte,&ord);err!=nil{
		return shim.Error("unmarshal error")
	}
	stoKey,err:=stub.CreateCompositeKey(StockKeyPrefix,[]string{ord.StockId})
	if err != nil {
		return shim.Error("create key error ")
	}
	stoByte,err:=stub.GetState(stoKey)
	if err != nil {
		return shim.Error("get state error ")
	}
	var sto Stock
	if err:=json.Unmarshal(stoByte,&sto);err!=nil{
		return shim.Error("unmarshal error ")
	}
	croKey,err:=stub.CreateCompositeKey(CropsKeyPrefix,[]string{ord.Purchase})
	if err != nil {
		return shim.Error("create key error")
	}
	croByte,err:=stub.GetState(croKey)
	if err!= nil {
		return shim.Error("get state error")
	}
	var cro Crops
	if err:=json.Unmarshal(croByte,&cro);err!=nil{
		return shim.Error("unmarshal error ")
	}
	back:=Back{
		Id:        "",
		Logistics: ord.Logistics,
		stock:     sto,
		Crops: cro,
	}
	backByte,err:=json.Marshal(back)
	if err != nil {
		return shim.Error("marshal error ")
	}
	return shim.Success(backByte)
}
//传入账号 、密码 、类型（ Company SubAccount)
func login(stub shim.ChaincodeStubInterface, args []string) pb.Response {
	filedres := filedchecking( args, 3)
	if filedres.Status != shim.OK {
		return pb.Response{
			Status:  filedres.Status,
			Message: filedres.Message,
			Payload: nil,
		}
	}
	//对输入密码进行MD5加密
	password := Hash(args[1], "md5", false, false)
	roleKey, err := stub.CreateCompositeKey(args[2], []string{args[0]})
	if err != nil {
		return shim.Error("create key error ")
	}
	roleByte, err := stub.GetState(roleKey)
	if err != nil {
		return shim.Error("get state error")
	}
	if len(roleByte)==0{
		return pb.Response{
			Status:               shim.ERRORTHRESHOLD,
			Message:              "未查询到用户",
			Payload:              nil,
		}
	}
	if args[2]=="Company"{
		var comp Company
		if err := json.Unmarshal(roleByte, &comp); err != nil {
			return shim.Error("unmarshal error")
		}
		if password != comp.Password {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "密码错误",
				Payload: nil,
			}
		}
	}
	if args[2]=="SubAccount"{
		var sub SubAccount
		if err := json.Unmarshal(roleByte, &sub); err != nil {
			return shim.Error("unmarshal error")
		}
		if password != sub.Password {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "密码错误",
				Payload: nil,
			}
		}
	}
	return shim.Success(nil)
}
func filedchecking(args []string, length int) pb.Response {
	if len(args) != length {
		return pb.Response{
			Status:  shim.ERRORTHRESHOLD,
			Message: "字段长度不符",
			Payload: nil,
		}
	}
	for i := 0; i < len(args); i++ {
		if args[i] == "" {
			return pb.Response{
				Status:  shim.ERRORTHRESHOLD,
				Message: "字段为空",
				Payload: nil,
			}
		}
	}
	return shim.Success(nil)
}
func Hash(src, CryptTool string, isHex bool, isDoubleCrypt bool) string { //加密算法
	var hash hash.Hash
	switch CryptTool {
	case "md5":
		hash = md5.New()
	case "sha1":
		hash = sha1.New()
	case "sha256":
		hash = sha256.New()
	case "sha512":
		hash = sha512.New()
	}
	if isHex {
		//如果加密串本身是16进制串需要做解析
		csrc, _ := hex.DecodeString(src)
		hash.Write(csrc)
	} else {
		hash.Write([]byte(src))
	}
	//一次加密后的结果
	cryptStr := fmt.Sprintf("%x", hash.Sum(nil))
	if isDoubleCrypt {
		//做二次加密
		hash.Reset()
		hash.Write([]byte(cryptStr))
		cryptStr = fmt.Sprintf("%x", hash.Sum(nil))
	}
	return cryptStr
}

const (
	CompanyKeyPrefix       = "Company"
	CompanyImgKeyPrefix	   = "CompanyImg"
	SubAccountKeyPrefix    = "SubAccount"
	SpaceKeyPrefix         = "Space"
	TestFertilityKeyPrefix = "TestFertility"
	AddFertilityKeyPrefix  = "AddFertility"
	FarmingKeyPrefix       = "Farming"
	CropsKeyPrefix         = "Crops"
	PickKeyPrefix          = "Pick"
	MachiningKeyPrefix     = "Machining"
	StockKeyPrefix         = "Stock"
	OrderKeyPrefix         = "Order"
	LogisticsKeyPrefix         = "Logistics"
	AssetsKeyPrefix        = "Assets" //  各结构体组合键前缀
	SpaceType1             = "土壤"
	SpaceType2             = "水塘" //场地类型
	AddFertilityType1      = "喷洒"
	AddFertilityType2      = "撒施" //施肥类型即施肥方式
	AssetsType1            = "种子"
	AssetsType2            = "鱼苗"
	AssetsType3            = "农药"
	AssetsType4            = "肥料"
	AssetsType5            = "饲料"
	//以上为各资产的类型
	CropsStatus1 = "发芽"
	CropsStatus2 = "幼苗期"
	CropsStatus3 = "植物期"
	CropsStatus4 = "开花期"
	CropsStatus5 = "繁殖期"
	CropsStatus6 = "结果期" //植物状态
	CropsType1   = "植物"
	CropsType2   = "动物"
	OrderStatus1="未完成"
	OrderStatus2="已完成"
	Ordertype1="未加工"
	Ordertype2="已加工"
)

type FarmingChaincode struct {
}
type Company struct { //农业公司账户 *为必填字段
	Id             string       `json:"id"`              //账户id*
	Password       string       `json:"password"`        //账户密码*
	Name           string       `json:"name"`            //企业名称*
	Address        string       `json:"address"`         //企业地址*
	Desc           string       `json:"desc"`            //企业相关信息
	EnterpriseCode string       `json:"enterprise_code"` //统一社会信用码*
	Phone          string       `json:"phone"`           //企业电话*
	Email          string       `json:"email"`           //企业邮箱*
	Website        string       `json:"website"`         //企业官网
	Subaccount     []SubAccount `json:"subaccount"`      //该企业下发的子账户
	Imgs		   []CompanyImg `json:"imgs"`
	Space          []Space      `json:"space"`           //公司所拥有的场地
	Assets         []Assets     `json:"assets"`          //所拥有的资产
	Storage        []Pick       `json:"storage"`         //采摘的农作物储存
	Machinings     []Machining  `json:"machinings"`      //加工过得农作物储存
}
type CompanyImg struct {
	Id			string `json:"id"`
	ImgName		string `json:"img_name"`
	Subjection  string `json:"subjection"`
}
type SubAccount struct { //企业下发的子账户
	Id         string `json:"id"`         //子账户id*
	Password   string `json:"password"`   //子账户密码*
	Name       string `json:"name"`       //下发给农户的真实姓名*
	Address    string `json:"address"`    //农户的住址*
	Phone      string `json:"phone"`      //农户的电话*
	Subjection string `json:"subjection"` //隶属的企业id*
}
type Space struct { //场地结构体
	Id            string          `json:"id"`            //场地id*
	Name          string          `json:"name"`          //场地名称*
	Subjection    string          `json:"subjection"`    //隶属的企业id*
	Address       string          `json:"address"`       //场地地址*
	Type          string          `json:"type"`          //场地类型（土壤类型）*
	Size          string          `json:"size"`          //场地大小*
	TestFertility []TestFertility `json:"fertility"`     //测试肥力
	AddFertility  []AddFertility  `json:"add_fertility"` //场地添加肥力记录
}
type TestFertility struct { //测试肥力结构体
	Id            string    `json:"id"`             //肥力id*
	Space         string    `json:"space"`          //场地id*
	CreateDate    time.Time `json:"create_date"`    //测试肥力的日期*
	Tester        string    `json:"tester"`         //测试人员的id即公司下发的子账户id*
	Type          string    `json:"type"`           //场地类型*
	OrganicMatter float64   `json:"organic_matter"` //有机质含量*  g/kg
	Alkali        float64   `json:"alkali"`         //碱解氮含量*  mg/kg
	Phosphorus    float64   `json:"phosphorus"`     //有效磷含量*  mg/kg
	Potassium     float64   `json:"potassium"`      //速效钾含量*  mg/kg
}
type AddFertility struct { //添加肥力结构体
	Id         string    `json:"id"`          //施肥id*
	Space      string    `json:"space"`       //场地id*
	CreateDate time.Time `json:"create_date"` //施肥日期*
	Name       string    `json:"name"`        //施肥名称*
	Fertility  string    `json:"fertility"`   //所施肥料id*
	Tester     string    `json:"tester"`      //施肥人员的id即公司下发的子账户id*
	Type       string    `json:"type"`        //施肥类型*
	Quality    float64   `json:"quality"`     //施肥质量* kg
}
type Farming struct { //农事管理结构体 不可修改
	Id         string    `json:"id"`          //农事id 这个id对于需要监控的农作物id 通过这个查询到农作物的一系列农事*
	CropsId    string    `json:"crops_id"`    //农作物id
	Name       string    `json:"name"`        //农事name*
	Space      string    `json:"space"`       //场地id*
	Tester     string    `json:"tester"`      //录入农事人员id及 公司下发的子账户*
	CreateTime time.Time `json:"create_time"` //录入时间*
	Type       string    `json:"type"`        //农事类型*
	Desc       string    `json:"desc"`        //农事备注*
}
type Pick struct { //采摘农作物 不可修改
	Id         string    `json:"id"`          //采摘农作物id 即这一批次农作物id*
	Name       string    `json:"name"`        //农作物名称
	Subjection string    `json:"subjection"`  //隶属的企业id*
	CropsId    string    `json:"crops_id"`    //需要采摘的农作物id*
	Tester     string    `json:"tester"`      //采摘人员id及 公司下发的子账户*
	CreateTime time.Time `json:"create_time"` //采摘时间*
	Weight     float64   `json:"weight"`      //采摘农作物的重量*
	Desc       string    `json:"desc"`        //农作物备注
}
type Machining struct { //加工农作物
	Id             string    `json:"id"`              //加工农作物id 即这一批次加工农作物id*
	Name           string    `json:"name"`            //加工产品名称*
	Subjection     string    `json:"subjection"`      //隶属的企业id*
	PickId         string    `json:"pick_id"`         //已经采摘的农作物id 即企业账户农作物库存的id*
	Tester         string    `json:"tester"`          //加工人员id及 公司下发的子账户*
	CreateTime     time.Time `json:"create_time"`     //加工时间*
	OriginalWeight float64   `json:"original_weight"` //原始重量*
	Weight         float64   `json:"weight"`          //加工过后的重量*
	Desc           string    `json:"desc"`            //加工备注
}
type Stock struct {
	Id         string    `json:"id"`         //这批次存储id*
	inTime     time.Time `json:"in_time"`    //入仓时间*
	outTime    time.Time `json:"out_time"`   //出仓时间
	StockId    []string  `json:"stock_id"`   //入仓产品id*
	Subjection string    `json:"subjection"` //隶属的企业id*
	inTester   string    `json:"in_tester"`  //入仓管理员id*
	outTester  string    `json:"out_tester"` //出仓管理员id
}
type Crops struct { //农作物种植结构体 记录该农作物的所有成长培育过程
	Id           string    `json:"id"`            //农作物id*
	Name         string    `json:"name"`          //农作物名称*
	Cycle        int64     `json:"cycle"`         //生长周期（天）*
	CreateTime   time.Time `json:"create_time"`   //创建时间
	PersonLiable string    `json:"person_liable"` //责任人id*
	Farmings     []Farming `json:"farmings"`      //农事记录
	Status       string    `json:"status"`        //农作物状态*
	Type         string    `json:"type"`          //植物还是动物*
}
type Order struct {//订单
	Id string `json:"id"`//订单id*
	Compid string `json:"compid"`//采购的公司
	Purchase string `json:"purchase"`//采购得农作物id*
	StockId string `json:"stock_id"`//储存id
	Type  string `json:"type"`//采购类型
	Weight float64 `json:"weight"`//采购的重量*
	Status string `json:"status"`//订单状态*
	CreateTime time.Time `json:"create_time"`//采购时间
	Logistics []Logistics `json:"logistics"`//物流信息
}
type Back struct {//追溯
	Id string `json:"id"`
	Logistics []Logistics `json:"logistics"`//运输的溯源
	stock  Stock `json:"stock"`//存储
	Crops Crops `json:"crops"`//种植
}
type Logistics struct {
	Id string `json:"id"`//id
	time time.Time `json:"time"`//检测时间
	Address string `json:"address"`//当前地址
	Temp float64 `json:"temp"`//检测温度
}
type Assets struct { //资产结构体
	Id           string    `json:"id"`            //资产id*
	Name         string    `json:"name"`          //资产名*
	Subjection   string    `json:"subjection"`    //隶属的企业id*
	PurchaseDate time.Time `json:"purchase_date"` //采购日期*
	Type         string    `json:"type"`          //资产类型 即种子 肥料 农药*
	Desc         string    `json:"desc"`          //资产规格*
	Production   string    `json:"production"`    //生产公司*
	OverdueDate  time.Time `json:"overdue_date"`  //过期时间*
}

func main() {
	//testQrCode()
	err := shim.Start(new(FarmingChaincode))
	if err != nil {
		fmt.Sprintf("链码启动失败")
	}
}
